﻿using System;
using System.Collections.Generic;
using System.Data;
using viForum.Classes;
using viForum.Providers;
using visinia.SmartEngine;
using visinia.SmartEngine.Cache;

namespace viForum.Controllers
{
    public class ThreadController
    {
        public static int AddThread(Thread thread)
        {
            IDataReader dr = viForumDataProvider.Provider.AddThread(thread.ForumId, thread.UserName, thread.Title, thread.Date, thread.Content);
            int index = 0;
            while (dr.Read())
            {
                if (dr[0] != Convert.DBNull)
                    index = (int)dr[0];
            }
            dr.Close();
            // not expiring "vf_thread" but just "vf" to expire the whole forum cache
            DataCache.DeleteCacheMultiple("vf");
            return index;
        }

        public static void UpdateThread(Thread thread)
        {
            viForumDataProvider.Provider.UpdateThread(thread.ThreadId, thread.ForumId, thread.UserName, thread.Title, thread.Date, thread.Content);
            DataCache.DeleteCacheMultiple("vf_thread");
        }

        public static void DeleteThread(int ThreadId)
        {
            viForumDataProvider.Provider.DeleteThread(ThreadId);
            // not expiring "vf_thread" but just "vf" to expire the whole forum cache
            DataCache.DeleteCacheMultiple("vf");
        }

        #region CACHE KEYS
        private const string KEY_THREADS_BY_FORUM = "vf_thread_by_forum_{0}";
        private const string KEY_THREAD_COUNT_BY_FORUM = "vf_thread_Count_by_forum_{0}";

        private const string KEY_THREAD_BY_URL = "vf_thread_by_Url_{0}";
        private const string KEY_THREAD = "vf_thread_{0}";
        private const string KEY_LATEST_THREAD = "vf_thread_latest_{0}";
        private const string KEY_LATEST_THREADS = "vf_thread_latest_AllForums{0}";

        #endregion

        public static List<Thread> GetThreads(int ForumId)
        {
            string key = string.Format(KEY_THREADS_BY_FORUM, ForumId);
            List<Thread> threads = (List<Thread>)DataCache.GetCache(key);
            if (threads == null)
            {
                threads = FillThreads(viForumDataProvider.Provider.GetThreads(ForumId));
                DataCache.SetCache(key, threads);
            }
            return threads;
        }

        public static Thread GetThread(int ThreadId)
        {
            string key = string.Format(KEY_THREAD, ThreadId);
            Thread thread = (Thread)DataCache.GetCache(key);
            if (thread == null)
            {
                thread = FillThread(viForumDataProvider.Provider.GetThread(ThreadId));
                DataCache.SetCache(key, thread);
            }
            return thread;
        }

        public static int GetThreadCount(int ForumId)
        {
            string key = string.Format(KEY_THREAD_COUNT_BY_FORUM, ForumId);
            if (DataCache.GetCache(key) == null)
            {
                IDataReader dr = viForumDataProvider.Provider.GetThreadCount(ForumId);
                int count = 0;
                while (dr.Read())
                {
                    if (dr[0] != Convert.DBNull)
                        count = (int)dr[0];
                }
                dr.Close();
                DataCache.SetCache(key, count);
            }
            return (int)DataCache.GetCache(key);
        }

        public static Thread GetLatestThread(int ForumId)
        {
            string key = string.Format(KEY_LATEST_THREAD, ForumId);
            Thread thread = (Thread)DataCache.GetCache(key);
            if (thread == null)
            {
                thread = FillThread(viForumDataProvider.Provider.GetLatestThread(ForumId));
                DataCache.SetCache(key, thread);
            }
            return thread;
        }

        public static List<Thread> GetLatestForumThreads(int Count)
        {
            string key = string.Format(KEY_LATEST_THREADS, Count);
            List<Thread> threads = (List<Thread>)DataCache.GetCache(key);
            if (threads == null)
            {
                threads = FillThreads(viForumDataProvider.Provider.GetLatestThreads(Count));
                DataCache.SetCache(key, threads);
            }
            return threads;
        }

        /// <summary>
        /// Generates the url for a thread
        /// </summary>
        /// <param name="thread">The thread for which to generate url</param>
        /// <returns>returns the thread url</returns>
        private static string GenerateUrl(Thread thread)
        {
            /*****************************************************************************************/
            // thread URL = Forum/Thread/ThreadId/ThreadTitle .aspx
            /*****************************************************************************************/
            string key = string.Format(KEY_THREAD_BY_URL, thread.ThreadId);
            string URL = (string)DataCache.GetCache(key);
            if (URL == null)
            {
                string threadId = thread.ThreadId.ToString();
                string title = thread.Title;
                URL = BaseController.viForumUrlSeparator + "/Thread/" + threadId + "/" + title + ".aspx";
                DataCache.SetCache(key, URL, new TimeSpan(0, 20, 0));
            }
            return URL;
        }

        #region HELPERS
        private static Thread FillThread(IDataReader dr)
        {
            while (dr.Read())
            {
                return ActualRead(dr, true);
            }
            return null;
        }

        private static List<Thread> FillThreads(IDataReader dr)
        {
            List<Thread> list = new List<Thread>();
            while (dr.Read())
            {
                list.Add(ActualRead(dr, false));
            }
            dr.Close();
            return list;
        }

        private static Thread ActualRead(IDataReader dr, bool CloseDataReader)
        {
            Thread thread = new Thread();
            if (dr["ThreadId"] != Convert.DBNull)
                thread.ThreadId = (int)dr["ThreadId"];
            if (dr["ForumId"] != Convert.DBNull)
                thread.ForumId = (int)dr["ForumId"];
            if (dr["UserName"] != Convert.DBNull)
                thread.UserName = (string)dr["UserName"];
            if (dr["Title"] != Convert.DBNull)
                thread.Title = (string)dr["Title"];
            if (dr["Date"] != Convert.DBNull)
                thread.Date = (DateTime)dr["Date"];
            if (dr["ThreadContent"] != Convert.DBNull)
                thread.Content = (string)dr["ThreadContent"];
            thread.Url = WebRoots.GetWebRoot + GenerateUrl(thread);
            if (CloseDataReader)
                dr.Close();
            return thread;
        }
        #endregion
    }
}
